#include "rest_api_adapter.h"

#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>

#include "base/pugixml.hpp"

#include "base/curl_client.h"
#include "base/url_encode.h"
#include "base/logging.h"

namespace imserver {

std::string AbsoluteShopUrl(const std::string & relative_url) {
  if (!relative_url.empty()) {
    if (relative_url[0] == '/') {
      return "http://bang.360.cn" + relative_url;
    }
  }
  return relative_url;
}

int RestApiAdapter::GetByTickets(const std::string & Q, const std::string & T, UserProfile * user) const {
  std::map<std::string, std::string> params;
  params.insert(std::make_pair("Q", Q));
  params.insert(std::make_pair("T", T));

  std::string xml = CurlGet("http://xianfei.bang.360.cn/apiim/ck_qt/", params);
  pugi::xml_document doc;

  if (doc.load(xml.c_str())) {
    const pugi::xml_node & root = doc.child("root");
    if (!root) {
      user->__set_qid(-1);
      LOG_WARN("RestApiAdapter GetBySession error, xml=" << xml);
      return -1;
    }
    int64_t qid = 0;
    try {
      qid = boost::lexical_cast<int64_t>(root.child_value("qid"));
    } catch (const boost::bad_lexical_cast & e) {
      return -2;
    }
    user->__set_qid(qid);
    user->__set_username(root.child_value("userName"));
    user->__set_nickname(root.child_value("nickName"));
    user->__set_head_pic(root.child_value("head_pic"));
    user->__set_shop_name(root.child_value("shopName"));
    user->__set_shop_url(AbsoluteShopUrl(root.child_value("shopUrl")));
    user->__set_shop_icon(root.child_value("shopIco"));

    // 针对bang商家做修改
    if (!user->shop_name.empty()) {
      user->username = user->shop_name;
    }
    if (!user->shop_icon.empty()) {
      user->head_pic = user->shop_icon;
    }
  }
  LOG_DEBUG("GetBySession ok, xml=" << xml);
  return 0;
}

int ParseUserProfiles(const pugi::xml_node & user_node, UserProfile * user) {
  if (!user_node) {
    return -1;
  }
  int64_t qid = 0;
  try {
    qid = boost::lexical_cast<int64_t>(user_node.child_value("qid"));
  } catch (const boost::bad_lexical_cast & e) {
    return -2;
  }
  user->__set_qid(qid);
  user->__set_username(user_node.child_value("userName"));
  user->__set_nickname(user_node.child_value("nickName"));
  user->__set_head_pic(user_node.child_value("imageUrl"));
  user->__set_shop_name(user_node.child_value("shopName"));
  user->__set_shop_url(AbsoluteShopUrl(user_node.child_value("shopUrl")));
  user->__set_shop_icon(user_node.child_value("shopIco"));
  LOG_DEBUG("parse image=" << user->head_pic);

  // 针对bang商家做修改
  if (!user->shop_name.empty()) {
    user->username = user->shop_name;
  }
  if (!user->shop_icon.empty()) {
    user->head_pic = user->shop_icon;
  }
  return 0;
}

int RestApiAdapter::Get(int64_t qid, UserProfile * user) const {
  std::map<std::string, std::string> post_args;
  post_args.insert(std::make_pair("qid", boost::lexical_cast<std::string>(qid)));

  std::string xml = CurlGet("http://xianfei.bang.360.cn/apiim/get_userinfo/", post_args);
  pugi::xml_document doc;

  if (doc.load(xml.c_str())) {
    const pugi::xml_node & root = doc.child("root");
    if (!root) {
      LOG_WARN("RestApiAdapter::Get() bad xml content : " << xml);
      return -1;
    }
    const pugi::xml_node & user_node = root.child("item");
    if (user_node) {
      LOG_DEBUG("RestApiAdapter::Get() ok. xml=" << xml);
      return ParseUserProfiles(user_node, user);
    }
  }
  LOG_WARN("RestApiAdapter::Get() error. xml=" << xml);
  return -3;
}

int RestApiAdapter::BatchGet(const std::vector<int64_t> & qids, UserProfileMap * users) const {
  if (qids.empty()) {
    LOG_WARN("BatchGet empty qids!");
    return 0;
  }
  std::map<std::string, std::string> post_args;
  std::stringstream ss;
  for(size_t i = 0; i < qids.size(); ++i) {
    if (i > 0) {
      ss << ',';
    }
    ss << qids[i];
  }
  post_args.insert(std::make_pair("qid", ss.str()));

  std::string xml = CurlGet("http://xianfei.bang.360.cn/apiim/get_userinfo/", post_args);
  pugi::xml_document doc;
  LOG_DEBUG("curlget xml=" << xml);

  if (!doc.load(xml.c_str())) {
    LOG_WARN("bad xml content : " << xml);
    return -1;
  }

  pugi::xml_node root = doc.child("root");
  if (!root) {
    LOG_WARN("no root ndoe! xml=" << xml);
    return -2;
  }
  for(pugi::xml_node item = root.child("item"); item; item = item.next_sibling("item")) {
    UserProfile u;
    if ((ParseUserProfiles(item, &u) == 0) && u.qid > 0) {
      users->insert(std::make_pair(u.qid, u));
    }
  }

  LOG_DEBUG("RestApiAdapter::BatchGet ok. qids=" << ss.str() << " xml=" << xml);
  return 0;
}

std::string RestApiAdapter::CurlGet(const std::string & url, const std::map<std::string, std::string> & args) const {
  std::string post_body;
  std::map<std::string, std::string>::const_iterator it = args.begin();
  for(; it != args.end(); ++it) {
    if (!post_body.empty()) {
      post_body += '&';
    }
    post_body += it->first;
    post_body += '=';
    post_body += base::UrlEncode(it->second);
  }

  std::string xml;
  int res = base::CurlClient::Instance().Post(url, post_body, &xml);
  if (res != 0) {
    LOG_WARN("CurlGet err, url=" << url << " body=" + post_body);
  } else {
    LOG_DEBUG("CurlGet ok, url=" << url << " body=" + post_body
             << " rsp=" + xml);
  }
  return xml;
}

}

